package com.ymm.system.core.facade;

import com.ymm.system.api.constants.LltorderEntity;
import com.ymm.system.api.dto.ShipperOrderDetailResponse;
import com.ymm.system.api.facade.SystemCargoService;
import com.ymm.system.api.facade.SystemOrderService;
import com.ymm.system.api.utils.*;
import com.ymm.system.core.constants.OpsPersonTypeEnum;
import com.ymm.system.core.mq.sender.*;
import com.ymm.system.dao.mapper.CargoMapper;
import com.ymm.system.dao.mapper.LltorderMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigInteger;
import java.util.Objects;

@Slf4j
@Service(version = "server")
@Component
public class SystemOrderServiceImpl implements SystemOrderService {

    @Resource
    private LltorderMapper lltorderMapper;

    @Resource
    private CargoMapper cargoMapper;

    @Resource
    private SystemCargoService systemCargoService;

    @Resource
    private CargoPullOffMsgSender cargoPullOffMsgSender;

    @Resource
    private OrderCancelMsgSender orderCancelMsgSender;

    @Resource
    private OrderConfirmMsgSender orderConfirmMsgSender;

    private static final double COMMISSION_PERCENTAGE = 0.1;

    /**
     * 取消订单 但不下架货源
     *
     * @param orderId       订单Id
     * @param opsPersonType 操作人类型，0表示货主，1表示司机，2表示客服，3表示系统，可以为空
     * @param opsPersonId   操作人Id，可以为空
     * @return 是否成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Boolean> cancelOrderWithoutPullOffCargo(Long orderId, Integer opsPersonType, Long opsPersonId,
                                                          Integer orderCancelReason, String orderCancelDescription) throws Exception {
        if (orderId == null) {
            log.info("参数输入错误");
            return Result.fail(false, ResultCodeEnum.PARAM_ERROR.getCode(), ResultCodeEnum.PARAM_ERROR.getMessage());
        }
        ShipperOrderDetailResponse orderDetail = lltorderMapper.getShipperOrderDetailByOrderId(orderId);

        lltorderMapper.updateOrderShipperStateByOrderId(orderId, OrderStatusEnum.CANCELLED.getCode());
        lltorderMapper.updateOrderCancelType(orderId, OrderCancelTypeCodeEnum.SHIPPER_CHANGE_DRIVER.getCode());
        if (orderCancelDescription == null) {
            orderCancelDescription = "";
        }
        if (orderCancelReason == null) {
            orderCancelReason = OrderCancelReasonCodeEnum.SHIPPER_NOT_WANT_DELIVER.getCode();
        }
        lltorderMapper.updateOrderCancelReason(orderId, orderCancelReason, orderCancelDescription);
        //重新回到上架状态，后续使用redis发布货源时应注意逻辑

        cargoMapper.updateCargoState(orderDetail.getCargoId(), CargoStatusEnum.ON_SHLFE.getCode());

        //给司机、货主后端发消息
        try {
            orderCancelMsgSender.send(orderId, orderDetail.getShipperId(), orderDetail.getDriverId(), orderDetail.getCargoId(), opsPersonType, opsPersonId);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("发送消息失败");
            throw e;
        }
        return Result.success(true);
    }

    /**
     * 取消订单 并且下架货源
     *
     * @param orderId       订单Id
     * @param opsPersonType 操作人类型，0表示货主，1表示司机，2表示客服，3表示系统，可以为空
     * @param opsPersonId   操作人Id，可以为空
     * @return 是否成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Boolean> cancelOrderWithPullOffCargo(Long orderId, Integer opsPersonType, Long opsPersonId,
                                                       Integer orderCancelReason, String orderCancelDescription) throws Exception {
        if (orderId == null) {
            return Result.fail(false, ResultCodeEnum.PARAM_ERROR);
        }
        ShipperOrderDetailResponse orderDetail = lltorderMapper.getShipperOrderDetailByOrderId(orderId);

        lltorderMapper.updateOrderShipperStateByOrderId(orderId, OrderStatusEnum.CANCELLED.getCode());
        lltorderMapper.updateOrderCancelType(orderId, OrderCancelTypeCodeEnum.SHIPPER_CANCEL_ORDER_PULL_OFF_CARGO.getCode());
        if (orderCancelDescription == null) {
            orderCancelDescription = "";
        }
        if (orderCancelReason == null) {
            orderCancelReason = OrderCancelReasonCodeEnum.SHIPPER_NOT_WANT_DELIVER.getCode();
        }
        lltorderMapper.updateOrderCancelReason(orderId, orderCancelReason, orderCancelDescription);
        //下架货源
        systemCargoService.cancelHodingCargo(orderDetail.getCargoId(), orderId, opsPersonType, opsPersonId);

        //给司机、货主后端发消息
        try {
            orderCancelMsgSender.send(orderId, orderDetail.getShipperId(), orderDetail.getDriverId(), orderDetail.getCargoId(), opsPersonType, opsPersonId);
            cargoPullOffMsgSender.send(orderDetail.getCargoId(), orderDetail.getShipperId(), orderId, opsPersonType, opsPersonId, orderDetail.getCargoPrice());
        } catch (Exception e) {
            e.printStackTrace();
            log.error("发送消息失败");
            throw e;
        }
        return Result.success(true);
    }

    @Override
    public Result<Boolean> cancelOrderByBackstage(Long orderId, Integer orderCancelType, Integer orderCancelReason, String orderCancelDescription) {
        if (orderId == null) {
            return Result.fail(false, ResultCodeEnum.PARAM_ERROR);
        }
        LltorderEntity lltorderEntity = lltorderMapper.getOrderDetailsByOrderId(orderId);
        if (!Objects.equals(lltorderEntity.getOrderCancelType(), OrderCancelTypeCodeEnum.ORDER_NOT_CANCEL.getCode())) {
            log.info("当前订单已取消，无法再次取消");
            return Result.fail(false, ResultCodeEnum.FAIL.getCode(), "订单已取消，无法再次取消");
        }
        if (orderCancelDescription == null) {
            orderCancelDescription = "";
        }
        if (orderCancelReason == null) {
            return Result.fail(false, ResultCodeEnum.PARAM_ERROR.getCode(), "参数参入错误");
        }
        if (Objects.equals(orderCancelType, OrderCancelTypeCodeEnum.DRIVER_CANCEL_ORDER_NOT_PULL_OFF_CARGO.getCode())) {
            try {
                this.cancelOrderWithoutPullOffCargo(orderId, OpsPersonTypeEnum.AGENT.getCode(), null, orderCancelReason, orderCancelDescription);
            } catch (Exception e) {
                e.printStackTrace();
                return Result.fail(false);
            }
            lltorderMapper.updateOrderCancelType(orderId, orderCancelType);
            return Result.success(true);
        } else if (Objects.equals(orderCancelType, OrderCancelTypeCodeEnum.DRIVER_CANCEL_ORDER_PULL_OFF_CARGO.getCode())) {
            try {
                this.cancelOrderWithPullOffCargo(orderId, OpsPersonTypeEnum.AGENT.getCode(), null, orderCancelReason, orderCancelDescription);
            } catch (Exception e) {
                e.printStackTrace();
                return Result.fail(false);
            }
            lltorderMapper.updateOrderCancelType(orderId, orderCancelType);
            return Result.success(true);
        } else {
            log.info("货主请通过货主端app取消");
            return Result.fail(false, ResultCodeEnum.PARAM_ERROR.getCode(), "货主请通过货主端app取消");
        }
    }

    /**
     * 确认收货
     *
     * @param orderId       订单Id
     * @param opsPersonType 操作人类型，0表示货主，1表示司机，2表示客服，3表示系统，可以为空
     * @param opsPersonId   操作人Id，可以为空
     * @return 是否成功
     */
    @Override
    public Result<Boolean> confirmReceipt(Long orderId, Integer opsPersonType, Long opsPersonId) throws Exception {
        if (orderId == null) {
            return Result.fail(false, ResultCodeEnum.PARAM_ERROR);
        }
        ShipperOrderDetailResponse orderDetail = lltorderMapper.getShipperOrderDetailByOrderId(orderId);
        BigInteger bigInteger = lltorderMapper.getDriverId(orderId);
        Long driverId = bigInteger.longValue();
        if (orderDetail.getOrderShipperState().equals(OrderStatusEnum.CANCELLED.getCode())) {
            log.info("订单已取消");
            return Result.fail(false, ResultCodeEnum.FAIL.getCode(), "订单已取消");
        } else if (orderDetail.getOrderShipperState().equals(OrderStatusEnum.COMPLETED.getCode())) {
            log.info("订单已完成");
            return Result.fail(false, ResultCodeEnum.FAIL.getCode(), "订单已完成");
        }

        lltorderMapper.updateOrderShipperStateByOrderId(orderId, OrderStatusEnum.COMPLETED.getCode());

        //给司机、货主后端发消息
        try {
            Integer collectPrice = (int) (orderDetail.getCargoPrice() * (1 - COMMISSION_PERCENTAGE));
            orderConfirmMsgSender.send(orderId, orderDetail.getShipperId(), driverId, orderDetail.getCargoId(), opsPersonType, opsPersonId, orderDetail.getCargoPrice(), collectPrice);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("发送消息失败");
            throw e;
        }
        return Result.success(true);
    }
}
